#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <libspe.h>
#include <math.h>
#include "structs.h"


extern spe_program_handle_t spu_handle;



#include <stdio.h>
#include <SDL/SDL.h>
#include <time.h>

#define WIDTH 1024
#define HEIGHT 768
#define BPP 4
#define DEPTH 32

static size_t count = 0;

uint32 RGBA( uint32 a, uint32 b, uint32 c, uint32 d )
{
	return a + ( b << 8 ) + ( c << 16 ) + ( d << 24 );
};

struct FBJob
{
	ProgramData pd __attribute__((aligned(16)));
	speid_t spe_id;

	FBJob() : spe_id( 0 ){};

	void KickJob( const ProgramData &_pd )
	{
		pd = _pd;
	
		if( spe_id == 0 )
		{
			spe_id = spe_create_thread( 0, &spu_handle, &pd, NULL, -1, 0 );
		}

	
		while( spe_stat_in_mbox(spe_id) == 0 );
		spe_write_in_mbox( spe_id, 1 );
	}

	void WaitForJob()
	{
		while( spe_read_out_mbox( spe_id ) == (unsigned int)-1 );
	}

};

void DrawScreen(SDL_Surface* screen, int h)
{

	count++;
	

	if(SDL_MUSTLOCK(screen))
	{
		if(SDL_LockSurface(screen) < 0) return;
	}


	ProgramData pd;
	pd.frameBuffer = screen->pixels;
	pd.width = screen->w;
	pd.height = screen->h;
	
	static double time = 0.0;
	
	time += 0.01;

	float f = 1.0f / 2.0f;


	float inner[16][2];
	float outer[16][2];
	
	for( int j = 0; j < 16; ++j )
	{
		float jf = time + j * 3.1415 * 2.0 / 16.0;
		float si = sin( jf );
		float co = cos( jf );
		inner[j][0] = si * 0.3f * f + 0.5f;
		inner[j][1] = co * 0.3f + 0.5f;
	}


	for( int j = 0; j < 16; ++j )
	{
		float jf = time + ( j + 0.5f ) * 3.1415 * 2.0 / 16.0;
		float si = sin( jf );
		float co = cos( jf );
		outer[j][0] = si * 0.45f * f + 0.5f;
		outer[j][1] = co * 0.45f + 0.5f;
	}



	for( int j = 0; j < 16; ++j )
	{
		int n = ( j + 1 ) & 15;
	
		
		pd.tr[j * 2].x[1] = inner[j][0];
		pd.tr[j * 2].y[1] = inner[j][1];
		pd.tr[j * 2].x[0] = outer[j][0];
		pd.tr[j * 2].y[0] = outer[j][1];
		pd.tr[j * 2].x[2] = inner[n][0];
		pd.tr[j * 2].y[2] = inner[n][1];
		pd.tr[j * 2].color = sin( 6.0f );

		
		pd.tr[j * 2 + 1].x[1] = inner[n][0];
		pd.tr[j * 2 + 1].y[1] = inner[n][1];
		pd.tr[j * 2 + 1].x[0] = outer[j][0];
		pd.tr[j * 2 + 1].y[0] = outer[j][1];
		pd.tr[j * 2 + 1].x[2] = outer[n][0];
		pd.tr[j * 2 + 1].y[2] = outer[n][1];
		pd.tr[j * 2 + 1].color = sin( 7.0f );
	}


	static FBJob jobs[4];

	for( int i = 0; i < 4; ++i )
	{	
		pd.ii = i;
		jobs[i].KickJob( pd );
	}

	
	for( int i = 0; i < 4; ++i )
	{	
		jobs[i].WaitForJob();
	}



	if(SDL_MUSTLOCK(screen))
	{
		SDL_UnlockSurface(screen);
	}

	SDL_Flip(screen);
}


int main(int argc, char* argv[])
{
	SDL_Surface *screen;
	SDL_Event event;

	int keypress = 0;
	int h=0;

	if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;

	if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_HWSURFACE)))
	{
		SDL_Quit();
		return 1;
	}



	while(!keypress)
	{
		DrawScreen(screen,h++);
		while(SDL_PollEvent(&event))
		{
			switch (event.type)
			{
					case SDL_QUIT:
					keypress = 1;
					break;
					case SDL_KEYDOWN:
					keypress = 1;
					break;
			}
		}
	}


	printf( "%i\n", count );

	SDL_Quit();

	return 0;
}


